<template>
  <div class="main flex flex-col gap-4 bg-white">
    <div class="cascader">
      <!-- 按列渲染，每列都有自己的搜索框和列表 -->
      <div
        v-for="(col, colIndex) in columns"
        :key="col.key"
        class="cascader-column"
      >
        <div class="column-header">
          <el-input
            v-model="col.keyword"
            size="small"
            placeholder="搜索该列..."
            clearable
            @input="onColumnKeywordInput(colIndex)"
          />
        </div>

        <div v-loading="col.loading" class="column-list">
          <el-scrollbar class="list-scroll">
            <div class="list-group">
              <el-button
                v-for="opt in col.filteredOptions"
                :key="opt.value"
                :type="opt.value === selectedPath[colIndex] ? 'success' : ''"
                link
                @click="onSelect(colIndex, opt)"
              >
                {{ opt.label }}
              </el-button>
            </div>

            <!-- 空/错误占位 -->
            <el-empty
              v-if="!col.loading && !col.filteredOptions.length"
              :description="col.error ? '加载失败' : '无数据'"
            />
          </el-scrollbar>
        </div>
      </div>
    </div>
    <div class="flex flex-col gap-4">
      <div class="flex justify-end items-center gap-4">
        <div class="text-sm text-gray-500">
          共
          <span style="color: var(--el-color-success)">
            {{ summaryText.count }}
          </span>
          个号码，预计生成
          <span style="color: var(--el-color-success)">
            {{ summaryText.totalStr }}
          </span>
          个号段
        </div>
        <el-button
          :disabled="!tableData.length"
          :loading="saving"
          type="success"
          @click="startDownload"
        >
          {{ saving ? "正在下载中" : "下载号码文件" }}
        </el-button>
      </div>
      <el-table show-overflow-tooltip stripe border :data="tableData">
        <el-table-column align="center" prop="countryCode" label="国际代码" />
        <el-table-column align="center" prop="countryName" label="国家" />
        <el-table-column align="center" prop="cityName" label="城市" />
        <el-table-column align="center" prop="areaCode" label="区域代码" />
        <el-table-column align="center" prop="snFrom" label="Sn From" />
        <el-table-column align="center" prop="snTo" label="Sn To" />
        <el-table-column align="center" prop="carrier" label="运营商名称" />
        <el-table-column align="center" label="操作" width="100">
          <template #default="scope">
            <el-button
              link
              type="danger"
              :icon="Delete"
              @click="onDelete(scope.row.id)"
            />
          </template>
        </el-table-column>
      </el-table>
    </div>
    <HugeDownloadDialog
      v-model="dialogVisible"
      :saving="saving"
      :filename="filename"
      :percent="percent"
      :written-lines="writtenLines"
      :total-lines="totalLines"
      :format-big-int="formatBigInt"
      @cancel="onCancel"
      @close="onDialogClose"
    />
  </div>
</template>

<script setup lang="ts">
import { Delete } from "@element-plus/icons-vue";
import { ref, onMounted, computed } from "vue";
import type { CascaderOption } from "element-plus";
import { ElMessage } from "element-plus";
import {
  getCountries,
  getCities,
  getAreaCodes,
  snRanges
} from "@/api/segmentTreeApi";
import { useUserStoreHook } from "@/store/modules/user";
import HugeDownloadDialog from "./HugeDownloadDialog.vue";
import { useHugeTextDownload, type NumberRow } from "./useHugeTextDownload";
const userStore = useUserStoreHook();
const pointsBalance = computed(
  () => userStore.currentUser?.user?.pointsBalance || 0
);
/**
  我们自渲染四列：
  0: 国家
  1: 城市
  2: 区号
  3: 号段
  每列：
  - keyword: 该列独立搜索词
  - rawOptions: 原始选项（来自接口 data）
  - filteredOptions: 过滤后的选项（渲染使用）
  - parentValue: 上一列当前选中的值（用于知道该列的父依赖）
  - loading、error：状态
 */

// 选中路径值（与列下标对应）
const selectedPath = ref<string[]>([]);

type ColumnState = {
  key: string; // 列唯一 key
  level: number; // 列级别(0..3)
  keyword: string;
  parentValue?: string | number; // 父列选中值
  loading: boolean;
  error: boolean;
  rawOptions: CascaderOption[]; // 原始未过滤
  filteredOptions: CascaderOption[]; // 过滤后
};

// 列数据
const columns = ref<ColumnState[]>([]);

// 工具：生成列 key
const columnKey = (level: number, parentValue?: string | number) =>
  `L${level}-${parentValue ?? "root"}`;

// 工具：过滤函数（大小写不敏感，label/value）
function filterOptions(options: CascaderOption[], kw: string) {
  if (!kw) return options;
  const k = kw.trim().toLowerCase();
  return options.filter(o => {
    const lab = String(o.label ?? "").toLowerCase();
    const val = String(o.value ?? "").toLowerCase();
    return lab.includes(k) || val.includes(k);
  });
}

// 占位节点（可按需）
const makeEmptyNode = (label = "无数据"): CascaderOption => ({
  value: `empty-${Date.now()}`,
  label,
  disabled: true,
  leaf: true
});

// 数据映射：根据你的后端字段，针对 data 做映射
const mapCountry = (c: any): CascaderOption => ({
  value: c.id,
  label: c.countryCode ? `${c.name}(+${c.countryCode})` : c.name,
  leaf: false,
  data: c
});
const mapCity = (c: any): CascaderOption => ({
  value: c.id,
  label: c.cityName,
  leaf: false,
  data: c
});
const mapAreaCode = (a: any): CascaderOption => ({
  value: a.id,
  label: `${a.areaName || "区号"}(${a.areaCode})`,
  leaf: false,
  data: a
});
const mapSegment = (s: any): CascaderOption => ({
  value: s.id,
  label: `${s.carrier}-${s.snFrom}-${s.snTo}`,
  leaf: true,
  data: s
});

// 加载某一列
async function loadColumn(level: number, parentValue?: string | number) {
  // 若需要重建该列（初始化或父发生变化）
  const idx = level;

  // 清理该列之后的列与选中值
  columns.value.splice(idx);
  selectedPath.value.splice(idx);

  // 初始化该列
  const col: ColumnState = {
    key: columnKey(level, parentValue),
    level,
    keyword: "", // 每列自己的搜索词
    parentValue,
    loading: true,
    error: false,
    rawOptions: [],
    filteredOptions: []
  };

  try {
    let list: any[] = [];
    if (level === 0) {
      const { data } = await getCountries();
      list = data || [];
      col.rawOptions = list.map(mapCountry);
    } else if (level === 1) {
      if (parentValue == null) {
        col.rawOptions = [];
      } else {
        const { data } = await getCities(String(parentValue));
        list = data || [];
        col.rawOptions = list.map(mapCity);
      }
    } else if (level === 2) {
      if (parentValue == null) {
        col.rawOptions = [];
      } else {
        const { data } = await getAreaCodes(String(parentValue));
        list = data || [];
        col.rawOptions = list.map(mapAreaCode);
      }
    } else if (level === 3) {
      if (parentValue == null) {
        col.rawOptions = [];
      } else {
        const { data } = await snRanges(String(parentValue));
        list = data || [];
        col.rawOptions = list.map(mapSegment);
      }
    }

    // 过滤并赋值
    col.filteredOptions = filterOptions(col.rawOptions, col.keyword);
    // 若无数据给占位
    if (!col.filteredOptions.length && !col.loading) {
      col.filteredOptions = [makeEmptyNode()];
    }
    col.loading = false;
    col.error = false;
  } catch (e) {
    console.error("loadColumn error:", e);
    col.loading = false;
    col.error = true;
    col.rawOptions = [];
    col.filteredOptions = [];
  } finally {
    columns.value[idx] = col;
  }
}

// 列搜索变更：过滤自身，并清空后续列
let typingTimer: number | null = null;
function onColumnKeywordInput(colIndex: number) {
  if (typingTimer) window.clearTimeout(typingTimer);
  // @ts-ignore
  typingTimer = window.setTimeout(() => {
    const col = columns.value[colIndex];
    if (!col) return;
    // 基于原始数据过滤
    col.filteredOptions = filterOptions(col.rawOptions, col.keyword);
    // 清空该列之后的列与选中值
    columns.value.splice(colIndex + 1);
    selectedPath.value.splice(colIndex + 1);
  }, 200);
}
const tableData = ref<any>([]);
const currentData = ref<any>([]);
// 选择某一列的项：设置该列选中值，并加载下一列
async function onSelect(colIndex: number, opt: any) {
  currentData.value[colIndex] = opt.data;
  const level = colIndex + 1;
  selectedPath.value[colIndex] = opt.value;
  const parentValue = selectedPath.value[colIndex];
  // 清空后续列
  columns.value.splice(colIndex + 1);
  selectedPath.value.splice(colIndex + 1);
  // 如果下一列存在，加载下一列
  if (level <= 3) {
    await loadColumn(level, parentValue);
  } else {
    const [country, city, area, segment] = currentData.value;
    const { countryCode, name: countryName } = country;
    const { cityName } = city;
    const { areaCode } = area;
    const { carrier, snFrom, snTo, id } = segment;
    const index = tableData.value.findIndex((item: any) => item.id === id);
    if (index === -1) {
      tableData.value.push({
        id,
        countryCode,
        countryName,
        cityName,
        areaCode,
        carrier,
        snFrom,
        snTo
      });
    }
  }
}

type Row = {
  countryCode: string;
  areaCode: string;
  snFrom: string;
  snTo: string;
};

function calcTotalLines(rows: Row[]): bigint {
  let total = 0n;
  for (const r of rows) {
    const from = BigInt(r.snFrom);
    const to = BigInt(r.snTo);
    if (to >= from) total += to - from + 1n;
  }
  return total;
}

function formatBigIntWithComma(n: bigint): string {
  // 千分位格式化（不使用 Intl，避免超大数精度丢失）
  return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

// rows 为你的列表响应式数据（ref 或 reactive 数组）
const summaryText = computed(() => {
  const count = tableData.value.length;
  const total = calcTotalLines(tableData.value);
  const totalStr = formatBigIntWithComma(total);
  return {
    count,
    totalStr
  };
});
const onDelete = (id: number) => {
  tableData.value = tableData.value.filter((item: any) => item.id !== id);
};
const dialogVisible = ref(false);

const {
  filename,
  saving,
  percent,
  writtenLines,
  totalLines,
  formatBigInt,
  start,
  cancel
} = useHugeTextDownload({
  linesPerFlush: 50_000,
  withBOM: true
});

async function startDownload() {
  if (pointsBalance.value <= 10) {
    ElMessage.warning("此功能须余额大于10积分才能使用");
    return;
  }
  dialogVisible.value = true;
  try {
    await start(tableData.value);
    if (!saving.value) {
      if (writtenLines.value === totalLines.value && totalLines.value > 0n) {
        ElMessage.success("生成完成");
        dialogVisible.value = false;
      } else if (totalLines.value > 0n) {
        ElMessage.warning("已取消");
      }
    }
  } catch (e: any) {
    ElMessage.error(e?.message ?? "生成失败");
  }
}

function onCancel() {
  cancel();
}
function onDialogClose() {
  // 需要时可处理关闭后的逻辑
}
// 初始化加载根列
onMounted(() => {
  loadColumn(0);
});
</script>

<style scoped lang="scss">
.main {
  padding: 16px;
  overflow: hidden;
  height: calc(100% - 48px);
}

.cascader {
  display: flex;
  align-items: stretch;
  gap: 12px;
  width: 100%;
  overflow-x: auto;
  flex-shrink: 0;
}

.cascader-column {
  flex: 0 0 360px;
  max-width: 360px;
  border: 1px solid #ebeef5;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  background: #fff;
}

.column-header {
  padding: 8px;
  border-bottom: 1px solid #ebeef5;
  background: #fafafa;
}

.column-list {
  position: relative;
  min-height: 280px;
}

.list-scroll {
  max-height: 320px;
}

.list-group {
  display: flex;
  flex-direction: column;
  padding: 8px;
  align-items: center;
  gap: 10px;
  .el-button + .el-button {
    margin-left: 0;
  }
  .el-button {
    max-width: 100%;
    white-space: normal;
    word-wrap: break-word;
    word-break: break-all;
    line-height: 16px;
  }
}

.placeholder {
  padding: 12px;
  color: #909399;
  text-align: center;
}

.footer {
  margin-top: 12px;
  color: #606266;
}
</style>
